/**
 * Definition for singly-linked list with a random pointer.
 * struct RandomListNode {
 *     int label;
 *     RandomListNode *next, *random;
 *     RandomListNode(int x) : label(x), next(NULL), random(NULL) {}
 * };
 */
class Solution {
private:
    unordered_map<RandomListNode*, RandomListNode*> memo;
public:
    RandomListNode *copyRandomList(RandomListNode *head) {
        if(!head) return NULL;
        if(memo.find(head) != memo.end()) return memo[head];
        RandomListNode* p = new RandomListNode(head -> label);
        memo[head] = p;
        // set elements for p
        p -> random = copyRandomList(head -> random);
        p -> next = copyRandomList(head -> next);
        return p;
    }
};
